package org.turl.utils;

import org.turl.annotations.instanceConverter;
import org.turl.annotations.convertible;
import org.turl.wrappers.WrapperToObject;
import org.turl.wrappers.Wrapper;

import java.lang.reflect.Constructor;

/**
 * Created by tonyx
 * User: tonyx
 * Date: May 24, 2008
 * Time: 12:49:57 PM
 */
public class MapOfConverterModularFactory extends ModularFactory{


    /**
     * is going to be deprecated: the map is not supposed to work for just one contract class
     * @param abstractionClass
     */
    public MapOfConverterModularFactory(Class abstractionClass) {
        super(abstractionClass);
    }

    public Object getObject(Object[] parameters) throws Exception {

        if ("".equals(currentImplementation)|| currentImplementation ==null) {
            throw new RuntimeException("currentImplementation not set");
        }
        if ("".equals(referenceImplementation)||referenceImplementation==null) {
            throw new RuntimeException("referenceImplementation not set");
        }

        if (referenceImplementation.equals(currentImplementation)) {
            return (implementations.get(currentImplementation)).newInstance(parameters);
        } else {
            return MapOfConverterModularFactory.getConverted(implementations.get(currentImplementation),implementations.get(referenceImplementation),parameters);
        }
    }

    protected static Object getConverted(Constructor targetConstructor,Constructor originConstructor,Object[] originParams) {
        try {

            Class firstContractClass = originConstructor.getAnnotation(convertible.class).contractClass();
            Class secondContractClass = targetConstructor.getAnnotation(convertible.class).contractClass();

            if (!firstContractClass.equals(secondContractClass)) {
                throw new IllegalArgumentException();
            }

            return ConversionMap.getInstance().getMappedInstance(originConstructor,targetConstructor,firstContractClass,originParams);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
